package controllers

import (
	"autoPage/models"
	"bytes"
	"context"
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/tls"
	"database/sql"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/pquerna/ffjson/ffjson"
	"github.com/sirupsen/logrus"
	"github.com/wxnacy/wgo/arrays"
	"io/ioutil"
	"log"
	"math"
	"math/rand"
	"net"
	"net/http"
	"net/url"
	"os"
	"reflect"
	"strconv"
	"strings"
	"time"
)
var allinkstr string

type DmsResStruct struct {
	Msg    string      `json:"msg"`
	Data   interface{} `json:"data"`
	Status bool        `json:"status"`
}

// logStruct struct 为了把log写成多线程，节省时间
type logStruct1 struct {
	data     interface{} // 数据
	msg      string      // 信息
	symbol   string      // 标志位
	level    string      // 级别
	filepath string      // 文件名
	filenum  int         // 文件行数
}

// Page struct
type Page struct {
	PageNo     int
	PageSize   int
	TotalPage  int
	TotalCount int
	FirstPage  bool
	LastPage   bool
	List       interface{}
}

/* start */

type ResZJFStruct struct {
	TaskId    string      `json:"taskId"`
	Domain    string      `json:"domain"`
	DeviceId  string      `json:"deviceId"`
	SkillId   string      `json:"skillId"`
	Timestamp int64       `json:"timestamp"`
	Type      string      `json:"type"`
	Data      interface{} `json:"data"`
}

type ALDeviceRes struct {
	DeviceId     string `json:"deviceId"`
	ErrorMessage string `json:"errorMessage"`
	Status       int    `json:"status"`
}
type AlResp struct {
	TaskId  string         `json:"taskId"`
	SkillId string         `json:"skillId"`
	Devices []*ALDeviceRes `json:"devices"`
}
type AlConfigItem struct {
	SkillId      string `json:"skillId"`
	SkillIdFull  string `json:"skillIdFull"`
	SkillConfig  string `json:"skillConfig"`
	TaskConfig   string `json:"taskConfig"`
	TaskId       string `json:"taskId"`
	Annotation   string `json:"annotation"`
	AlgorithmUrl string `json:"algorithmUrl"`
}
type AlDevice struct {
	DevId         string          `json:"devId"`
	ChannelId     string          `json:"channelId"`
	DeviceId      string          `json:"deviceId"`
	DataType      string          `json:"dataType"`
	DeviceName    string          `json:"deviceName"`
	DeviceConfig  string          `json:"deviceConfig"`
	StreamUrl     string          `json:"streamUrl"`
	Config        []*AlConfigItem `json:"config"`
	InterfaceType string          `json:"interfaceType"`
	InterfaceInfo interface{}     `json:"interfaceInfo"`
	Domain        string          `json:"domain"`
}
type AlActionInfo struct {
	Devices       []*AlDevice `json:"devices"`
	InterfaceType string      `json:"interfaceType"`
	InterfaceInfo interface{} `json:"interfaceInfo"`
}
type OrmCount struct {
	Count int64 `  orm:"column(count)" json:"count"`
}
type UpdateRoiStruct struct {
	Domain     string `json:"domain"`
	DeviceId   string `json:"deviceId"`
	SkillId    string `json:"skillId"`
	TaskId     string `json:"taskId"`
	Annotation string `json:"annotation"`
	Marking    string `json:"marking"`
}
type RoiStruct struct {
	Roi          string `json:"roi"`
	DeviceConfig string `json:"deviceConfig"`
	Marking      string `json:"marking"`
}

type ViewUrl struct {
	Url string `json:"url"`
}
type ViewUrlRes struct {
	Code int64    `json:"code"`
	Msg  string   `json:"msg"`
	Data *ViewUrl `json:"data"`
}

type AlControlStruct struct {
	Domain     string        `json:"domain"`
	Action     string        `json:"action"`
	ActionInfo *AlActionInfo `json:"actionInfo"`
}

const (
	StatusWrongJson    = "wrongJson"
	StatusWrongAction  = "wrongAtion"
	StatusStartSuccess = "started"
	StatusStopSuccess  = "stopped"
	StatusStartFailed  = "startFailed"
	StatusLocked       = "locked"
	StatusStopFailed   = "stopFailed"
	DecodePrefix       = "decode_"
	StartAction        = "start"
	StatusAction       = "status"
	StopAction         = "stop"

	OilSysId   = "oil"
	SpzlSysId  = "spzl"
	AtlasSysId = "atlas"
	ZkrSysId   = "zkr"

	PAGECONFIG_MENU = "pageconfig" //页面配置
	LISTCONFIG_MENU = "listconfig" //列表配置
	SYSCONFIG_MENU  = "sysconfig"  //系统配置
	INDEXPAGE_MENU  = "index"      //主页
	ALGORITHM_MENU  = "algorithm"  //算法配置

	timefmt    = "2006-01-02 15:04:05"
	timefmtstr = "20060102150405"
	datefmt    = "2006-01-02"
	hmfmt      = "15:04"

	AlStarted     = 1
	AlStartFailed = -1
	AlStopped     = 2
	AlStopFailed  = -2
)

func (d *BaseController) ALHealth() {
	dms := DmsResStruct{
		Status: true,
		Msg:    "ok",
		Data:   nil,
	}
	d.ResReturn(dms)
}

// PageUtil 分页
func PageUtil(count int, pageNo int, pageSize int, list interface{}) Page {
	tp := count / pageSize
	if count%pageSize > 0 {
		tp = count/pageSize + 1
	}
	return Page{PageNo: pageNo, PageSize: pageSize, TotalPage: tp, TotalCount: count, FirstPage: pageNo == 1, LastPage: pageNo == tp, List: list}
}

type BaseController struct {
	beego.Controller
	drs DmsResStruct
}

var r *rand.Rand
var LastTime int64

func (bc *BaseController) GetUID() string {
	uid := bc.GetSession("uid")
	return strconv.Itoa(uid.(int))
}
func (bc *BaseController) GetUidInt() int {
	uid := bc.GetSession("uid")
	return uid.(int)
}
func (bc *BaseController) GetUserName() string {
	uname, _ := bc.GetSession("username").(string)
	return uname
}
func (bc *BaseController) GetUserId() string {
	uid := bc.GetSession("uname")
	if uid == nil {
		return ""
	}
	return uid.(string)
}
func (bc *BaseController) GetUrlQuery() url.Values {
	if bc.Ctx != nil {
		return bc.Ctx.Request.URL.Query()
	}
	return nil

}

func (bc *BaseController) Prepare() {

	controller, action := bc.GetControllerAndAction()
	if controller == "LoginController" || (controller == "TranshistoryController" && action == "GetAlerts") ||
		(controller == "ApiController" && (action == "Health" ||
			action == "AlControl" ||
			action == "SetRoi" ||
			action == "GetRoi" ||
			action == "SetScanConfig" ||
			action == "GetScanConfig" ||
			action == "GetPreviewUrl" ||
			action == "ViewChannel")) ||
		(controller == "AlHostController" && (action == "Add" || action == "ViewHost")) ||
		(controller == "DefaultController" &&
			(action == "Health" ||
				action == "GetPreviewUrl" ||
				action == "GetRoi" ||
				action == "SetRoi" || action == "SetScanConfig" ||
				action == "GetScanConfig" ||
				action == "GetPreviewUrl" ||
				action == "AlControl")) {
	} else {
		sessionUname := bc.GetUserName()
		sessionUid := bc.GetUserId()
		if len(sessionUname) == 0 {
			bc.Ctx.Redirect(302, "/login/")
			return
		}
		bc.Data["uname"] = sessionUname
		bc.Data["uid"] = sessionUid
		menus, _ := models.GetMenu()
		bc.Data["Menus"] = menus
	}
	bc.Data["viewpath"] = "/static"

	sysId := beego.AppConfig.String("SysInfo::sysId")
	sysname := beego.AppConfig.String("SysInfo::" + sysId + "_Name")
	bc.Data["sysId"] = sysId
	bc.Data["sysname"] = sysname
	compName := beego.AppConfig.String("compName")
	bc.Data["compName"] = compName
	compLogo := beego.AppConfig.String("compLogo")
	bc.Data["compLogo"] = compLogo
}

func init() {
	r = rand.New(rand.NewSource(time.Now().Unix()))
	LastTime = time.Now().Local().Unix()
	fmt.Println("开始：", LastTime)
	dbsrc := beego.AppConfig.String("MYSQL::dbsrc")
	host := beego.AppConfig.String("MYSQL::host")
	dbn := beego.AppConfig.String("MYSQL::AUTOPAGE")
	allinkstr = dbsrc + "@tcp(" + host + ")/" + dbn
}

func (bc *BaseController) strToInt32(s string) (v int32, err error) {
	int10, err := strconv.ParseInt(s, 10, 32)
	if err == nil {
		v = int32(int10)
	}
	return
}
func floatToString(f float64) string {
	return strconv.FormatFloat(f, 'f', -1, 32)
}
func intToString(i int64) string {
	return strconv.FormatInt(i, 10)
}
func boolToString(b bool) string {
	if b {
		return "true"
	} else {
		return "false"
	}
}
func ToString(arg interface{}) string {
	switch arg.(type) {
	case bool:
		return boolToString(arg.(bool))
	case float32:
		return floatToString(float64(arg.(float32)))
	case float64:
		return floatToString(arg.(float64))
	case int:
		return intToString(int64(arg.(int)))
	case int8:
		return intToString(int64(arg.(int8)))
	case int16:
		return intToString(int64(arg.(int16)))
	case int32:
		return intToString(int64(arg.(int32)))
	case int64:
		return intToString(int64(arg.(int64)))
	case map[string]interface{}:
		argbyte, err := ffjson.Marshal(arg)
		if err != nil {
			return ""
		} else {
			return string(argbyte)
		}
	default:
		return fmt.Sprint(arg)
	}
}

func (dc *BaseController) DealContainer(cids, dcsHost, dockerAction string) (res DmsResStruct, err error) {
	if cids == "" {
		return res, errors.New("cid is required")
	}
	cidArr := strings.Split(cids, ",")
	var alRes DmsResStruct
	for i := 0; i < len(cidArr); i++ {
		if strings.TrimSpace(cidArr[i]) == "" {
			continue
		}
		stopUrl := fmt.Sprintf("%v/dcs/%s?cid=%v", dcsHost, dockerAction, cidArr[i])
		data, err := dc.GetRequestData("GET", nil, stopUrl, 180*time.Second)
		if err != nil {
			beego.Error(dockerAction, " docker failed:", err.Error())
			return res, err
		}
		err = json.Unmarshal(data, &alRes)
		if err != nil {
			beego.Error(err.Error())
			return res, err
		}
		if alRes.Status == false {
			beego.Error(alRes.Msg)
			return res, errors.New(alRes.Msg)
		}
		res = alRes
		beego.Info(dockerAction, " container ", cidArr[i], " success")
	}
	return
}

func (bc *BaseController) GetRequestData(method string, argus map[string]interface{}, apiUrl string, timeout time.Duration) (data []byte, err error) {
	paramsStr, _ := json.Marshal(argus)
	reader := bytes.NewReader([]byte(paramsStr))
	if method == "" {
		method = "POST"
	}
	if timeout == 0 {
		timeout = 60 * time.Second
	}

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		DialContext: func(ctx context.Context, netw, addr string) (net.Conn, error) {
			deadline := time.Now().Add(timeout)
			c, err := net.DialTimeout(netw, addr, timeout)
			if err != nil {
				return nil, err
			}
			c.SetDeadline(deadline)
			tcp_conn := c.(*net.TCPConn)
			tcp_conn.SetKeepAlive(false)
			return c, nil
		}, DisableKeepAlives: true}
	client := http.Client{Transport: tr, Timeout: timeout}
	request, err := http.NewRequest(method, apiUrl, reader)
	if err != nil {
		return nil, err
	}
	request.Header.Add("content-type", "application/json")
	request.Header.Add("Connection", "close")
	resp, err := client.Do(request)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	if resp.StatusCode == 200 {
		data, err = ioutil.ReadAll(resp.Body)
	} else {
		err = errors.New(resp.Status)
	}
	return
}

func (bc *BaseController) GetRequestDataNew(method string, argus map[string]interface{}, apiUrl string, timeout time.Duration, auth map[string]string) (data []byte, err error) {
	paramsStr, _ := json.Marshal(argus)
	reader := bytes.NewReader([]byte(paramsStr))
	if method == "" {
		method = "POST"
	}
	if timeout == 0 {
		timeout = 60 * time.Second
	}

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		DialContext: func(ctx context.Context, netw, addr string) (net.Conn, error) {
			deadline := time.Now().Add(timeout)
			c, err := net.DialTimeout(netw, addr, timeout)
			if err != nil {
				return nil, err
			}
			c.SetDeadline(deadline)
			tcp_conn := c.(*net.TCPConn)
			tcp_conn.SetKeepAlive(false)
			return c, nil
		}, DisableKeepAlives: true}
	client := http.Client{Transport: tr, Timeout: timeout}
	request, err := http.NewRequest(method, apiUrl, reader)
	if err != nil {
		return nil, err
	}
	request.Header.Add("content-type", "application/json")
	request.Header.Add("Connection", "close")
	if auth != nil {
		for k, v := range auth {
			request.Header.Add(k, v)
		}
	}
	resp, err := client.Do(request)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	if resp.StatusCode == 200 {
		data, err = ioutil.ReadAll(resp.Body)
	} else {
		err = errors.New(resp.Status)
	}
	return
}

func (bc *BaseController) MD5(s string) (md5s string) {
	b := md5.Sum([]byte(s))
	md5s = hex.EncodeToString(b[:])
	return
}

func (bc *BaseController) SHA(s string) (shas string) {
	sha1 := sha1.New()
	sha1.Write([]byte(s))
	return hex.EncodeToString(sha1.Sum([]byte("")))
}

func (bc *BaseController) HmacSha256(message string, secret string) string {
	key := []byte(secret)
	h := hmac.New(sha256.New, key)
	h.Write([]byte(message))
	sha := hex.EncodeToString(h.Sum(nil))
	return sha
	//return base64.StdEncoding.EncodeToString([]byte(sha))
}
func (bc *BaseController) Base64Encode(s string) string {
	return base64.StdEncoding.EncodeToString([]byte(s))
}
func (bc *BaseController) Base64Decode(s string) (sDec []byte, err error) {
	sDec, err = base64.StdEncoding.DecodeString(s)
	return
}

// check is submit
func (bc *BaseController) IsSubmit() bool {
	v := bc.Input()
	_, ok := v["submit"]
	return ok
}

func (bc *BaseController) RandStr(len int) string {
	bytes := make([]byte, len)
	for i := 0; i < len; i++ {
		b := r.Intn(26) + 65
		bytes[i] = byte(b)
	}
	return string(bytes)
}

func (bc *BaseController) ResReturn(res DmsResStruct) {
	if res.Status {
		bc.Ctx.Output.SetStatus(200)
	}
	json := make(map[string]interface{})
	json["status"] = res.Status
	json["msg"] = res.Msg
	json["data"] = res.Data
	bc.Data["json"] = json
	bc.ServeJSON()
	return
}

// writeLogFile把写日志变成多线程
func (bc *BaseController) writeInfoFile(ch chan logStruct1) {
	infoName := `info_` + time.Now().Format("2006-01-02") + `.log`
	loginfofile := beego.AppConfig.String("logdir") + infoName
	controller, action := bc.GetControllerAndAction()
	mych := <-ch
	var err error
	logFile, err := os.OpenFile(loginfofile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	defer logFile.Close()
	if err != nil {
		log.Println("error opening file: ", err.Error())
	}
	logger := logrus.New()
	logger.SetOutput(logFile)

	message := ""
	switch mych.symbol {
	case "str":
		message = mych.data.(string)
	default:
		c, _ := json.Marshal(mych.data)
		message = string(c)
	}
	logger.Formatter = &logrus.TextFormatter{}
	f := logrus.Fields{
		"file":       fmt.Sprintf("%s:%d", mych.filepath, mych.filenum),
		"controller": controller,
		"action":     action,
		"data":       message,
	}
	switch mych.level {
	case "error":
		logger.WithFields(f).Error(mych.msg)
	case "info":
		logger.WithFields(f).Info(mych.msg)
	default:
		logger.WithFields(f).Info(mych.msg)
	}

}
func (bc *BaseController) ShowMsg(msg, url string, waitsec int) {
	beego.Info(msg)
	data := make(map[string]interface{})
	data["type"] = false
	data["title"] = "跳转提示"
	data["msg"] = msg
	if waitsec == 0 {
		waitsec = 3
	}
	data["wait"] = waitsec
	if url == "-1" {
		url = bc.Ctx.Request.Referer()
	} else if url == "-2" {
		url = bc.Ctx.Request.Referer()
	}
	data["url"] = url
	bc.Data["res"] = data
	bc.TplName = "msg.html"
}

//获取界面提交的值
func (dc *BaseController) GetAddedContent(configId string) map[string]interface{} {
	addItems := models.GetAddContent(configId)
	m := make(map[string]interface{})
	for i := 0; i < len(addItems); i++ {
		m[addItems[i]] = dc.getFormData(addItems[i])
	}
	return m
}
func (c *BaseController) getFormData(field string) interface{} {
	if c.Ctx != nil && len(c.Ctx.Request.Form[field]) > 0 {
		return strings.Join(c.Ctx.Request.Form[field], "|")
	}
	return nil
}

func (c *BaseController) getLocalTimestamp() (timestamp int64) {
	if local, err := time.LoadLocation("Local"); err == nil {
		timestamp = time.Now().In(local).Unix()
	} else {
		timestamp = time.Now().Unix()
	}
	return
}

//haomiao
func (c *BaseController) getLocalTimestampHm() (timestamp int64) {
	if local, err := time.LoadLocation("Local"); err == nil {
		timestamp = time.Now().In(local).UnixNano() / 1e6
	} else {
		timestamp = time.Now().UnixNano() / 1e6
	}
	return
}

//判斷文件夾是否存在
func (c *BaseController) PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func (b *BaseController) MkDir(dir string) error {
	exist, err := b.PathExists(dir)
	if err != nil {
		beego.Error("get dir error![%]\n", err)
		return err
	}
	if exist == false {
		err := os.Mkdir(dir, os.ModePerm)
		if err != nil {
			beego.Error("mkdir failed [%v]\n", err)
			return err
		} else {
			beego.Info("mkdir success %v", dir)
		}
	}
	return nil
}

// 主要逻辑就是先乘，trunc之后再除回去，就达到了保留N位小数的效果
func (b *BaseController) FormatFloat(num float64, decimal int) string {
	// 默认乘1
	d := float64(1)
	if decimal > 0 {
		// 10的N次方
		d = math.Pow10(decimal)
	}
	// math.trunc作用就是返回浮点数的整数部分
	// 再除回去，小数点后无效的0也就不存在了
	return strconv.FormatFloat(math.Trunc(num*d)/d, 'f', -1, 64)
}

func (b BaseController) StrIndexOf(s string, arr []string) bool {
	for _, v := range arr {
		if s == v {
			return true
		}
	}
	return false
}

func (a *BaseController) ExecuteNoquery(linkstr, sqlstr string) (err error) {
	db, err := sql.Open("mysql", linkstr)
	if err != nil {
		fmt.Println("open db failed")
		return
	}
	rows, err := db.Query(sqlstr)
	if err != nil {
		beego.Info("query failed:", err.Error())
		return
	}
	defer rows.Close()
	return
}

func (a *BaseController) GetTableList(linkstr, sqlstr string) (headers []string, data []interface{}, err error) {
	db, err := sql.Open("mysql", linkstr)
	if err != nil {
		beego.Error("open db failed")
		return
	}

	db.SetConnMaxLifetime(4 * 60 * time.Second)
	rows, err := db.Query(sqlstr)
	if err != nil {
		beego.Info("query failed:", err.Error(), ";linkstr:", linkstr, ";sqostr:", sqlstr)
		return
	}
	defer rows.Close()

	colTypes, err := rows.ColumnTypes()
	if err != nil {
		beego.Info("ColumnTypes failed:", err.Error())
		return
	}

	for _, v := range colTypes {
		headers = append(headers, v.Name())
	}
	for rows.Next() {
		var built = make([]interface{}, 0)

		for _, ct := range colTypes {
			switch ct.DatabaseTypeName() {
			case "VARCHAR":
				fallthrough

			case "DATETIME", "TEXT":
				built = append(built, new(sql.NullString))
			case "INT":
				built = append(built, new(sql.NullInt64))
			case "TINYINT":
				built = append(built, new(sql.NullInt64))
			default:
				var i interface{}
				built = append(built, &i)
				fmt.Printf("type name is %v\n", ct.DatabaseTypeName())
			}

		}

		err = rows.Scan(built...)
		if err != nil {
			fmt.Println(err)
			continue
		}
		var vs = make([]interface{}, len(built))
		for i, v := range built {
			//if vv, ok := v.(interface{}); ok {
			//	vs = append(vs, vv)
			//}
			vv := reflect.TypeOf(v)
			switch vv.String() {
			case "*sql.NullInt64":
				vss, _ := v.(*sql.NullInt64).Value()
				vs[i] = vss
			case "*sql.NullString":
				vss, _ := v.(*sql.NullString).Value()
				vs[i] = vss
			default:
				vs[i] = v
			}
		}
		data = append(data, vs)
	}
	return
}

//时间戳转时间
func (a *BaseController) UnixToStr(timeUnix int64, formatstr string) string {
	timeStr := time.Unix(timeUnix, 0).Format(formatstr)
	return timeStr
}

//时间转时间戳
func (a *BaseController) StrToUnix(timeStr, formatstr string) (int64, error) {
	local, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		return 0, err
	}
	tt, err := time.ParseInLocation(formatstr, timeStr, local)
	if err != nil {
		return 0, err
	}
	timeUnix := tt.Unix()
	return timeUnix, nil
}
func (b BaseController) GetTableData(tableNamen, tableName, task_id, device_id string, pageSize, offset int64) (count int64, headers []string, data []interface{}, err error) {
	o := orm.NewOrm()
	ds := new(OrmCount)
	sql := fmt.Sprintf("  SELECT count(*)as count FROM %s", tableNamen)
	ti := strings.TrimSpace(task_id)
	di := strings.TrimSpace(device_id)
	var sqlstr bytes.Buffer
	sqlstr.WriteString("select * from " + tableNamen)
	hasTaskId := []string{"config"}
	hasDeviceId := []string{"status", "config"}
	if (ti != "" || di != "") && (arrays.Contains(hasTaskId, tableName) >= 0 || arrays.Contains(hasDeviceId, tableName) >= 0) {
		sql += " where "
		sqlstr.WriteString(" where ")
		var wheresql = ""
		if ti != "" && arrays.Contains(hasTaskId, tableName) >= 0 {
			wheresql += "and task_id like '%" + ti + "%'"
		}
		if di != "" && arrays.Contains(hasDeviceId, tableName) >= 0 {
			wheresql += "and device_id like '%" + di + "%'"
		}
		wheresql = strings.TrimPrefix(wheresql, "and")
		sql += wheresql
		sqlstr.WriteString(wheresql)
	}

	err = o.Raw(sql).QueryRow(&ds)

	if err == nil {
		count = ds.Count
	}

	//if strings.TrimSpace(tableName) == "logs" {
	//	sqlstr.WriteString(" order by create_time desc  ")
	//} else {
	sqlstr.WriteString(" order by id desc  ")
	//}
	sqlstr.WriteString(fmt.Sprintf(" limit %v  offset %v", pageSize, offset))
	headers, data, err = b.GetTableList(allinkstr, sqlstr.String())
	return
}

//更新密码
func (dc *BaseController) SavePass() {
	var p models.UserChangePass
	dms := DmsResStruct{
		Msg:    "",
		Data:   nil,
		Status: false,
	}

	err := dc.ParseForm(&p)
	if err != nil {
		dms.Msg = err.Error()
		dc.ResReturn(dms)
		return
	}

	oldPass := p.OldPass
	newPass := p.NewPass
	uname := p.Uid
	newpassAgain := p.Newpassagain
	if newpassAgain != newPass {
		dms.Msg = "新密码两次输入不一致!"
		dc.ResReturn(dms)
		return
	}
	if newPass == oldPass {
		dms.Msg = "新旧密码一样，请重新输入新密码!"
		dc.ResReturn(dms)
		return
	}
	res := models.GetUserByNameAndPwd(uname, dc.MD5(oldPass))
	if len(res) == 1 {
		res[0].Pwd = dc.MD5(newPass)
		err := models.UpdateUserById(res[0])
		if err == nil {
			dms.Msg = "ok"
			dms.Status = true
		} else {
			dms.Msg = err.Error()
		}
	} else {
		dms.Msg = "旧密码输入错误"
	}
	dc.ResReturn(dms)
}
